<html>
<head><meta charset="utf-8"><title>Why does `InferCtxt::evaluate_obligation` go through tcx? · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html">Why does `InferCtxt::evaluate_obligation` go through tcx?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="223074163"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074163" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074163">(Jan 18 2021 at 01:41)</a>:</h4>
<p>I just found the following code: <a href="https://github.com/rust-lang/rust/blob/4253153db205251f72ea4493687a31e04a2a8ca0/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs#L69-L72">https://github.com/rust-lang/rust/blob/4253153db205251f72ea4493687a31e04a2a8ca0/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs#L69-L72</a></p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="w">        </span><span class="c1">// Run canonical query. If overflow occurs, rerun from scratch but this time</span>
<span class="w">        </span><span class="c1">// in standard trait query mode so that overflow is handled appropriately</span>
<span class="w">        </span><span class="c1">// within `SelectionContext`.</span>
<span class="w">        </span><span class="bp">self</span><span class="p">.</span><span class="n">tcx</span><span class="p">.</span><span class="n">evaluate_obligation</span><span class="p">(</span><span class="n">c_pred</span><span class="p">)</span><span class="w"></span>
</code></pre></div>
<p>The query for <code>tcx.evaluate_obligation</code> says</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="w">        </span><span class="sd">/// Do not call this query directly: invoke `infcx.predicate_may_hold()` or</span>
<span class="w">        </span><span class="sd">/// `infcx.predicate_must_hold()` instead.</span>
<span class="w">        </span><span class="n">query</span><span class="w"> </span><span class="n">evaluate_obligation</span><span class="p">(</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">)</span><span class="w"></span>
</code></pre></div>
<p>and the implementation is over in <code>rustc_traits</code>: <a href="https://github.com/rust-lang/rust/blob/4253153db205251f72ea4493687a31e04a2a8ca0/compiler/rustc_traits/src/evaluate_obligation.rs#L14">https://github.com/rust-lang/rust/blob/4253153db205251f72ea4493687a31e04a2a8ca0/compiler/rustc_traits/src/evaluate_obligation.rs#L14</a></p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">evaluate_obligation</span><span class="o">&lt;'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="p">(</span><span class="w"></span>
<span class="w">    </span><span class="n">tcx</span>: <span class="nc">TyCtxt</span><span class="o">&lt;'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">canonical_goal</span>: <span class="nc">CanonicalPredicateGoal</span><span class="o">&lt;'</span><span class="na">tcx</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">EvaluationResult</span><span class="p">,</span><span class="w"> </span><span class="n">OverflowError</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</code></pre></div>
<p>What's going on here? Why not just have this inline in the same file instead of going through the query system?</p>



<a name="223074226"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074226" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074226">(Jan 18 2021 at 01:44)</a>:</h4>
<p>query system caches things?</p>



<a name="223074277"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074277" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074277">(Jan 18 2021 at 01:45)</a>:</h4>
<p>why not have it provided in the same crate, then?</p>



<a name="223074283"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074283" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074283">(Jan 18 2021 at 01:45)</a>:</h4>
<p>and anyway it seems silly to use the query system <em>just</em> for caching, you could use an in-memory cache for that</p>



<a name="223074528"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074528" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074528">(Jan 18 2021 at 01:52)</a>:</h4>
<p>well, caching both on disk and in memory?</p>



<a name="223074532"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074532" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074532">(Jan 18 2021 at 01:52)</a>:</h4>
<p>I guess I'm confused why you call this out specifically</p>



<a name="223074535"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074535" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074535">(Jan 18 2021 at 01:52)</a>:</h4>
<p>because it's only used once, within one crate</p>



<a name="223074537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074537">(Jan 18 2021 at 01:52)</a>:</h4>
<p>the crate split is probably just a matter of being refactored over time</p>



<a name="223074540"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074540" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074540">(Jan 18 2021 at 01:52)</a>:</h4>
<p>and it <em>explicitly</em> says not to use it anywhere else</p>



<a name="223074550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074550">(Jan 18 2021 at 01:53)</a>:</h4>
<p>also it's making <a href="https://github.com/rust-lang/rust/issues/81091">https://github.com/rust-lang/rust/issues/81091</a> harder because it means OverflowError has to be in rustc_middle instead of rustc_trait_selection</p>



<a name="223074605"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074605" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074605">(Jan 18 2021 at 01:54)</a>:</h4>
<p>I guess - if there's no performance impact to removing it, seems fine to do so, but I'd expect a drop from the lack of caching (presumably that is why it is a query)</p>



<a name="223074609"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074609" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074609">(Jan 18 2021 at 01:54)</a>:</h4>
<p>sounds good, I'll remove it and run perf</p>



<a name="223074616"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074616" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074616">(Jan 18 2021 at 01:55)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116122">simulacrum</span> <a href="#narrow/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F/near/223074528">said</a>:</p>
<blockquote>
<p>well, caching both on disk and in memory?</p>
</blockquote>
<p>evaluate_obligation is not cached on disk: <a href="https://github.com/rust-lang/rust/blob/4253153db205251f72ea4493687a31e04a2a8ca0/compiler/rustc_middle/src/query/mod.rs#L1536">https://github.com/rust-lang/rust/blob/4253153db205251f72ea4493687a31e04a2a8ca0/compiler/rustc_middle/src/query/mod.rs#L1536</a></p>



<a name="223074733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074733">(Jan 18 2021 at 01:58)</a>:</h4>
<p>uh, why do you say so?</p>



<a name="223074735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074735">(Jan 18 2021 at 01:58)</a>:</h4>
<p>is it not the default?</p>



<a name="223074739"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074739" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074739">(Jan 18 2021 at 01:58)</a>:</h4>
<p>I don't think so, no</p>



<a name="223074741"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074741" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074741">(Jan 18 2021 at 01:58)</a>:</h4>
<p>hmm let me double check that</p>



<a name="223074742"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074742" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074742">(Jan 18 2021 at 01:58)</a>:</h4>
<p>I am pretty confident it is the default</p>



<a name="223074748"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074748" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074748">(Jan 18 2021 at 01:59)</a>:</h4>
<p>maybe <code>cache_on_disk_if</code> is saying when <em>not</em> to cache on disk</p>



<a name="223074755"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223074755" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223074755">(Jan 18 2021 at 01:59)</a>:</h4>
<p>well, rather, limiting the cases, but yeah that'd be my guess</p>



<a name="223075264"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223075264" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223075264">(Jan 18 2021 at 02:13)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116122">simulacrum</span> <a href="#narrow/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F/near/223074532">said</a>:</p>
<blockquote>
<p>I guess I'm confused why you call this out specifically</p>
</blockquote>
<p>maybe the diff will help, it's deleting 50 lines with almost no added code: <a href="https://github.com/rust-lang/rust/pull/81150/files">https://github.com/rust-lang/rust/pull/81150/files</a></p>



<a name="223097516"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Why%20does%20%60InferCtxt%3A%3Aevaluate_obligation%60%20go%20through%20tcx%3F/near/223097516" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Why.20does.20.60InferCtxt.3A.3Aevaluate_obligation.60.20go.20through.20tcx.3F.html#223097516">(Jan 18 2021 at 09:35)</a>:</h4>
<p>Even if it isn't directly cached on disk, it is still a barier for the red-green system, allowing rustc to realize earlier that a change doesn't affect any of the users of this query and thus doesn't need to recompute them.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>